//
// Created by LinorInk on 2024/3/17.
//
#include "utils.h"
#include "task.h"

taskTypedef *firstTask = NULL;

/**
 * 注册任务
 * @param task 任务定义
 * @param tick 间隔执行时间
 * @param times 重复次数
 * @param method 调用方法
 * @return
 */
uint8_t Task_regist(taskTypedef *task, uint16_t tick, uint8_t times, void (*method)(void)) {
    task->tick = tick;
    task->count = times;
    task->pFunction = method;
    if (firstTask == NULL) {
        firstTask = task;
        task->nextTask = NULL;
        return 0;
    }

    task->nextTask = firstTask;
    firstTask = task;

    task->lastUpdateTick = HAL_GetTick();

    return 0;
}

uint8_t Task_remove(taskTypedef *task) {
    taskTypedef *indexTask = firstTask;
    if (firstTask == NULL) {
        return 1;
    }

    if (indexTask == task) {
        firstTask = indexTask->nextTask;
        return 0;
    }
    taskTypedef *previousTask = firstTask;
    indexTask = indexTask->nextTask;
    while (indexTask->nextTask != NULL) {
        if (indexTask == task) {
            previousTask->nextTask = indexTask->nextTask;
            return 0;
        }
        previousTask = indexTask;
        indexTask = indexTask->nextTask;
    }
    return 1;
}

void Task_update() {
    taskTypedef *taskIndex = firstTask;
    taskTypedef *previousTask = NULL;
    while (taskIndex != NULL) {
        if (getDTime(taskIndex->lastUpdateTick) >= taskIndex->tick) {
            if (taskIndex->count > 0) {
                taskIndex->pFunction();
                taskIndex->lastUpdateTick = HAL_GetTick(); // 更新时间戳
                if(taskIndex->count != 0xFF) taskIndex->count--;
            }
            if (taskIndex->count == 0) {
                // 删除任务
                if(previousTask == NULL) {
                    // 删除头节点
                    firstTask = taskIndex->nextTask;
                    taskIndex = taskIndex->nextTask;
                    continue;
                } else {
                    // 删除中间节点
                    previousTask->nextTask = taskIndex->nextTask;
                    taskIndex = taskIndex->nextTask;
                    continue;
                }
            }
        }
        previousTask = taskIndex;
        taskIndex = taskIndex->nextTask;
    }
}
